package com.zhuoyue.biz.core.api.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhuoyue.biz.core.api.dao.DeviceDao;
import com.zhuoyue.biz.core.api.domain.DeviceAndGatewayDO;
import com.zhuoyue.biz.core.api.domain.DeviceDO;
import com.zhuoyue.biz.core.api.dto.rep.GroupRepDTO;
import com.zhuoyue.biz.core.api.dto.req.ControlReq;
import com.zhuoyue.biz.core.api.service.*;
import com.zhuoyue.biz.core.command.cmd.common.faa.MultiFunctionSwitch0Faa8A09;
import com.zhuoyue.biz.core.command.cmd.common.faa.base.MultiFunctionSwitch0Faa8A09Utils;
import com.zhuoyue.common.constant.LinkageCurtainActionsJson;
import com.zhuoyue.common.constant.LinkageLightActionsJson;
import com.zhuoyue.common.constant.LinkageRgbwActionsJson;
import com.zhuoyue.common.exception.ErrorType;
import com.zhuoyue.common.exception.ZyServerException;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhuoyue.biz.core.api.dao.TblZigbeeDeviceLinkageRelationMapper;
import com.zhuoyue.biz.core.api.domain.TblZigbeeDeviceLinkageRelation;

/**
 * @author wjming
 * @ClassName: TblZigbeeDeviceLinkageRelationServiceImpl
 * @Description:
 * @Date 2021-07-14 20:06
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TblZigbeeDeviceLinkageRelationServiceImpl extends ServiceImpl<TblZigbeeDeviceLinkageRelationMapper, TblZigbeeDeviceLinkageRelation> implements TblZigbeeDeviceLinkageRelationService {

    private final GatewayRedisService gatewayRedisService;
    private final DeviceService deviceService;
    private final GroupService groupService;
    private final DeviceDao deviceDao;
    private final StringRedisTemplate redisTemplate;

    private static final String ADD = "add";
    private static final String UPDATE = "update";
    private static final String DELETE = "delete";
    private static final String SET_MODE = "SETMODE";
    private static final String SET_BRIGHTNESS = "setBrightness";
    /**
     * deviceType+productType
     */
    private static final String DEVICE_PRODUCT_TYPE_0D02 = "0D02";
    private static final String SET_COLOR_TEMPERATURE = "setColorTemperature";
    private static final String DURATION = "duration";
    private static final String MODE_STATE = "modeState";
    /**
     * 调光
     */
    private static final String ADJUST_BRIGHTNESS = "AdjustBrightness";
    /**
     * 调色
     */
    private static final String ADJUST_COLOR = "AdjustColor";
    private static final String TURN_OFF_REQUEST = "TurnOffRequest";

    @Override
    public Boolean linkAgeSet(String startDeviceId,
                              String endId, String endType, String startSwitchState, String actions, String mode, String type) {


        //向设备发送联动数据帧
        String deviceType = "";
        String endDeviceMac = "";
        DeviceAndGatewayDO deviceAndGatewayDO = new DeviceAndGatewayDO();
        if (ADD.equals(type)) {
            deviceAndGatewayDO = deviceDao.selectUseCmdByMac(startDeviceId);
        } else if (UPDATE.equals(type)) {
            deviceAndGatewayDO = deviceDao.selectUseCmdByMac(startDeviceId);
        } else if (DELETE.equals(type)) {
            QueryWrapper<TblZigbeeDeviceLinkageRelation> queryWrapper1 = new QueryWrapper();
            queryWrapper1.eq("start_device_id", startDeviceId);
            List<TblZigbeeDeviceLinkageRelation> list = list(queryWrapper1);
            if (list.size() < 1) {
                return false;
            }
            QueryWrapper<DeviceDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("zigbee_mac", list.get(0).getStartDeviceMac());
            queryWrapper.eq("product_type", list.get(0).getStartProductType());
            DeviceDO one = deviceService.getOne(queryWrapper);
            deviceAndGatewayDO = deviceDao.selectUseCmdByMac(one.getId());
        }

        ControlReq controlReq = new ControlReq();
        controlReq.setControlType("linkageRequest");
        String way = StringUtils.substringAfter(deviceAndGatewayDO.getProductType(), "_");
        way = StringUtils.isEmpty(way) ? "1" : way;
        String modeCmd = "";
        Map<String, Object> actions1 = new HashMap(16);
        String endDeviceState = "";
        switch (endType) {
            case "device":
                DeviceDO deviceById = deviceService.getDeviceById(endId);
                try {
                    endDeviceMac = deviceById.getZigbeeMac();
                } catch (Exception e) {
                    String deleteGroupType = "delete";
                    if (StringUtils.equals(deleteGroupType, type)) {
                        return true;
                    }
                }

                switch (deviceById.getDeviceType() + deviceById.getProductType()) {
                    //静音窗帘
                    case "0E02":
                        deviceType = "curtain";
                        LinkageCurtainActionsJson linkageCurtainActionsJson = new LinkageCurtainActionsJson();
                        if (StringUtils.isNotEmpty(actions)) {
                            JSONObject jsonObject = JSONObject.parseObject(actions);
                            linkageCurtainActionsJson.setState(jsonObject.get("state").toString());
                            linkageCurtainActionsJson.setPercentage(jsonObject.get("percentage") != null ? Integer.parseInt(jsonObject.get("percentage").toString()) : null);
                            endDeviceState = jsonObject.get("state").toString();
                        }


                        actions1.put("endDeviceMac", endDeviceMac);
                        actions1.put("startSwitchState", startSwitchState);
                        actions1.put("way", way);
                        actions1.put("mode", mode);
                        actions1.put("linkageCurtainActionsJson", linkageCurtainActionsJson);
                        actions1.put("deviceType", deviceType);
                        controlReq.setActions(actions1);
                        break;
                    //双色温
                    case "0D02":
                        //单色温
                    case "0D03":
                        //开关控制盒
                    case "0D04":
                        deviceType = "light";
                        LinkageLightActionsJson linkageLightActionsJson = new LinkageLightActionsJson();
                        if (StringUtils.isNotEmpty(actions)) {
                            JSONObject jsonObject = JSONObject.parseObject(actions);
                            linkageLightActionsJson.setState(jsonObject.get("state").toString());

                            //若是设置模式
                            if (SET_MODE.equals(linkageLightActionsJson.getState())) {
                                linkageLightActionsJson.setModeIndex(Integer.parseInt(jsonObject.get("modeIndex").toString()));
                                actions1.put("modeIndex", linkageLightActionsJson.getModeIndex());
                            }
                            endDeviceState = jsonObject.get("state").toString();

                            //亮度，单色温、双色温有，开关控制盒没有
                            if (jsonObject.containsKey(SET_BRIGHTNESS)) {
                                linkageLightActionsJson.setSetBrightness(Integer.parseInt(jsonObject.get(SET_BRIGHTNESS).toString()));
                            }

                            //双色温有色温，单色温、开关控制盒没有
                            if (DEVICE_PRODUCT_TYPE_0D02.equals(deviceById.getDeviceType() + deviceById.getProductType())) {
                                if (jsonObject.containsKey(SET_COLOR_TEMPERATURE)) {
                                    linkageLightActionsJson.setSetColorTemperature(Integer.parseInt(jsonObject.get(SET_COLOR_TEMPERATURE).toString()));
                                }
                            }

                            //挡位
                            if (jsonObject.containsKey(DURATION)) {
                                linkageLightActionsJson.setDuration(Integer.parseInt(jsonObject.get("duration").toString()));
                            } else {
                                linkageLightActionsJson.setDuration(0);
                            }
                        }


                        actions1.put("endDeviceMac", endDeviceMac);
                        actions1.put("startSwitchState", startSwitchState);
                        actions1.put("way", way);
                        actions1.put("mode", mode);
                        actions1.put("linkageLightActionsJson", linkageLightActionsJson);
                        actions1.put("deviceType", deviceType);
                        actions1.put("odDeviceProductType", deviceById.getOdIndex() + deviceById.getDeviceType() + deviceById.getProductType());
                        controlReq.setActions(actions1);
                        break;

                    //灯带控制器2.0
                    case "0B03":
                        LinkageRgbwActionsJson linkageRgbwActionsJson = new LinkageRgbwActionsJson();
                        deviceType = "rgbw";
                        if (StringUtils.isNotEmpty(actions)) {
                            //将actions字符串转换为json对象
                            JSONObject actionsJson = JSONObject.parseObject(actions);
                            //设置需要存储到数据库中的actions的值
                            String state = actionsJson.get("state").toString();
                            String modeState = "";
                            linkageRgbwActionsJson.setType(deviceType);

                            linkageRgbwActionsJson.setState(state);
                            if (actionsJson.containsKey(MODE_STATE)) {
                                modeState = actionsJson.get(MODE_STATE).toString();
                                linkageRgbwActionsJson.setModeState(modeState);
                            }
                            //若是调光或调色，则有"duration"
                            if (ADJUST_BRIGHTNESS.equals(state) || ADJUST_COLOR.equals(state) || TURN_OFF_REQUEST.equals(state)) {
                                linkageRgbwActionsJson.setDuration(Integer.parseInt(actionsJson.get("duration").toString()));
                            }
                            //若是调光，则有"white"
                            if (ADJUST_BRIGHTNESS.equals(state)) {
                                linkageRgbwActionsJson.setWhite(Integer.parseInt(actionsJson.get("white").toString()));
                            }

                            if (ADJUST_COLOR.equals(state)) {
                                linkageRgbwActionsJson.setRed(Integer.parseInt(actionsJson.get("red").toString()));
                                linkageRgbwActionsJson.setGreen(Integer.parseInt(actionsJson.get("green").toString()));
                                linkageRgbwActionsJson.setBlue(Integer.parseInt(actionsJson.get("blue").toString()));
                            }

                        }
                        actions1.put("endDeviceMac", endDeviceMac);
                        actions1.put("startSwitchState", startSwitchState);
                        actions1.put("way", way);
                        actions1.put("mode", mode);
                        actions1.put("linkageRgbwActionsJson", linkageRgbwActionsJson);
                        actions1.put("deviceType", deviceType);
                        actions1.put("odDeviceProductType", deviceById.getOdIndex() + deviceById.getDeviceType() + deviceById.getProductType());
                        controlReq.setActions(actions1);
                        break;
                    default:
                        break;
                }
                break;
            case "group":
                GroupRepDTO groupRepDTO = null;
                try {
                    groupRepDTO = groupService.selectGroupsDetailsById(endId);
                } catch (ZyServerException e) {
                    String deleteGroupType = "delete";
                    if (e.getCode() == ErrorType.result_not_exist.getCode() && StringUtils.equals(deleteGroupType, type)) {
                        return true;
                    }
                }

                deviceType = groupRepDTO.getType();
                endDeviceMac = groupRepDTO.getCode() + "00000000000000";
                actions1.put("endDeviceMac", endDeviceMac);
                actions1.put("startSwitchState", startSwitchState);
                actions1.put("way", way);
                actions1.put("mode", mode);
                actions1.put("deviceType", deviceType);

                switch (deviceType) {
                    case "light":
                        LinkageLightActionsJson linkageLightActionsJson = new LinkageLightActionsJson();
                        if (StringUtils.isNotEmpty(actions)) {
                            JSONObject jsonObject = JSONObject.parseObject(actions);

                            linkageLightActionsJson.setState(jsonObject.get("state").toString());
                            endDeviceState = jsonObject.get("state").toString();

                            if (SET_MODE.equals(linkageLightActionsJson.getState())) {
                                linkageLightActionsJson.setModeIndex(Integer.parseInt(jsonObject.get("modeIndex").toString()));
                                actions1.put("modeIndex", linkageLightActionsJson.getModeIndex());
                            }

                            if (jsonObject.containsKey(SET_BRIGHTNESS)) {
                                linkageLightActionsJson.setSetBrightness(Integer.parseInt(jsonObject.get(SET_BRIGHTNESS).toString()));
                            }

                            if (jsonObject.containsKey(SET_COLOR_TEMPERATURE)) {
                                linkageLightActionsJson.setSetColorTemperature(Integer.parseInt(jsonObject.get(SET_COLOR_TEMPERATURE).toString()));
                            }

                            linkageLightActionsJson.setDuration(Integer.parseInt(jsonObject.get("duration").toString()));
                        }
                        actions1.put("linkageLightActionsJson", linkageLightActionsJson);
                        controlReq.setActions(actions1);
                        break;
                    case "curtain":
                        LinkageCurtainActionsJson linkageCurtainActionsJson = new LinkageCurtainActionsJson();
                        if (StringUtils.isNotEmpty(actions)) {
                            JSONObject jsonObject = JSONObject.parseObject(actions);

                            linkageCurtainActionsJson.setState(jsonObject.get("state").toString());
                            endDeviceState = jsonObject.get("state").toString();
                            linkageCurtainActionsJson.setPercentage(jsonObject.get("percentage") != null ? Integer.parseInt(jsonObject.get("percentage").toString()) : null);

                        }

                        actions1.put("linkageCurtainActionsJson", linkageCurtainActionsJson);

                        controlReq.setActions(actions1);
                        break;
                    case "rgbw":
                        JSONObject actionsJson = JSONObject.parseObject(actions);
                        LinkageRgbwActionsJson linkageRgbwActionsJson = new LinkageRgbwActionsJson();

                        if (StringUtils.isNotEmpty(actions)) {
                            String state = actionsJson.get("state").toString();
                            String modeState = "";
                            linkageRgbwActionsJson.setState(state);

                            if (actionsJson.containsKey(MODE_STATE)) {
                                modeState = actionsJson.get(MODE_STATE).toString();
                                linkageRgbwActionsJson.setModeState(modeState);
                            }
                            //若是调光或调色，则有"duration"
                            if (ADJUST_BRIGHTNESS.equals(state) || ADJUST_COLOR.equals(state) || TURN_OFF_REQUEST.equals(state)) {
                                linkageRgbwActionsJson.setDuration(Integer.parseInt(actionsJson.get("duration").toString()));
                            }
                            //若是调色，则有"white"
                            if (ADJUST_BRIGHTNESS.equals(state)) {
                                linkageRgbwActionsJson.setWhite(Integer.parseInt(actionsJson.get("white").toString()));
                            }
                            //若是调色或设置呼吸灯模式，则有rgb
                            if (ADJUST_COLOR.equals(state)) {
                                linkageRgbwActionsJson.setRed(Integer.parseInt(actionsJson.get("red").toString()));
                                linkageRgbwActionsJson.setGreen(Integer.parseInt(actionsJson.get("green").toString()));
                                linkageRgbwActionsJson.setBlue(Integer.parseInt(actionsJson.get("blue").toString()));
                            }
                        }

                        actions1.put("linkageRgbwActionsJson", linkageRgbwActionsJson);
                        controlReq.setActions(actions1);
                        break;
                    default:
                        break;
                }

                break;
            default:
                break;
        }
        String childIndex = "";
        System.out.println("模式：" + mode);
        System.out.println("源设备开关：" + startSwitchState);
        childIndex = MultiFunctionSwitch0Faa8A09Utils.index(startSwitchState, mode, way);


        JSONObject jsonObject = new JSONObject();
        jsonObject.put("deviceMac", deviceAndGatewayDO.getZigbeeMac());
        jsonObject.put("odIndex", deviceAndGatewayDO.getOdIndex());
        jsonObject.put("productType", deviceAndGatewayDO.getProductType());
        jsonObject.put("startSwitchState", startSwitchState);
        jsonObject.put("startDeviceId", startDeviceId);
        jsonObject.put("mode", mode);
        jsonObject.put("deviceType", deviceAndGatewayDO.getDeviceType());
        jsonObject.put("endSwitchState", endDeviceState);
        redisTemplate.opsForValue().set("zyzn_linkage_set_gatewayMac_" + deviceAndGatewayDO.getGatewayMac() + "_device_" + deviceAndGatewayDO.getZigbeeMac() + "_index_" + childIndex, String.valueOf(jsonObject), 5, TimeUnit.SECONDS);
        System.out.println("向redis中存放数据");
        //向网关发送命令
        String cmd = MultiFunctionSwitch0Faa8A09.control(deviceAndGatewayDO, controlReq, way);
        gatewayRedisService.writeDataToGateway(deviceAndGatewayDO.getGatewayMac(), cmd);
        System.out.println("cmd" + cmd);
        return true;
    }
}
